package com.xci.sys.api;

import com.xci.core.base.ApiController;
import com.xci.core.base.RestMessage;
import com.xci.core.domain.FileModel;
import com.xci.core.domain.UploadInfo;
import com.xci.core.exceptions.AppException;
import com.xci.core.exceptions.ValidException;
import com.xci.core.helper.Helper;
import com.xci.core.internal.Const;
import com.xci.core.internal.Sys;
import io.swagger.annotations.*;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;

/**
 * 上传下载接口
 * @author 吕艳阳
 */
@ApiSort(13)
@Api(tags = "上传下载接口")
@Controller
@RequestMapping(value = "/api/sys/fileUpload", produces = Const.P_JSON)
public class UploadApiController extends ApiController {
    @ApiOperationSupport(order = 1)
    @ApiOperation(value = "上传文件")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "uFile", value = "上传的文件", required = true, dataType = "__File"),
            @ApiImplicitParam(name = "remotePath")
    })
    @ResponseBody
    @PostMapping("/upload")
    public RestMessage<FileModel> upload(MultipartFile uFile, @RequestParam(required = false) String remotePath) {
        //String appId = ApiHelper.currentApp().getId();
        //MultiValueMap<String, MultipartFile> multipartFiles = (
        //(StandardMultipartHttpServletRequest) request).getMultiFileMap();
        if(uFile == null) {
            return RestMessage.fail("请指定要上传的文件");
        }
        remotePath = remotePath.replace("\\","/");
        RestMessage<UploadInfo> result = Sys.me().uploadFile(uFile, remotePath);
        if(result.isSuccess()) {
            UploadInfo uploadInfo = result.getData();
            FileModel fileModel = new FileModel();
            fileModel.setId(Helper.nextIdStr());
            fileModel.setName(uploadInfo.getName());
            fileModel.setContentType(uploadInfo.getContentType());
            fileModel.setUrl(uploadInfo.getUrl());
            fileModel.setSize(uploadInfo.getSize());
//            File rfile = FileHelper.buildRootFile(uploadInfo.getUrl());
//            try(FileInputStream fis = new FileInputStream(rfile)) {
//                fileModel.setMd5(DigestUtils.md5Hex(fis));
//            }
            return RestMessage.success(fileModel);
            //uploadInfo.setUrl(Paths.get(uploadInfo.getUrl()).getName().toString());
        }
        return RestMessage.fail(result.getMsg());
    }

    @ApiOperationSupport(order = 2)
    @ApiOperation(value = "下载文件")
    @ApiImplicitParams({@ApiImplicitParam(name = "path", value = "文件路径", required = true), @ApiImplicitParam(name = "md5", value = "md5")})
    @ResponseBody
    @PostMapping(value = "/download", produces = {Const.P_OCTET, Const.P_JSON})
    public void download(@RequestParam String path, @RequestParam(required = false) String md5, HttpServletResponse response) throws IOException {
        if(Helper.isBlank(path)) {
            throw new ValidException("请指定下载文件名称");
        }
        path = path.replace("\\","/");
        File file = Sys.buildFile(path);
        if(!file.exists()) {
            throw new ValidException("无效的文件名称");
        }
        //md5一致,默认不传输
        if(Helper.isNotBlank(md5)) {
            String smd5 = DigestUtils.md5Hex(new FileInputStream(file));
            if(smd5.equalsIgnoreCase(md5)) {
                response.setContentType("application/md5-identical");
                return;
            }
        }

        response.setContentLengthLong(file.length());
        response.setContentType("application/octet-stream");
        response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
        response.setHeader("Pragma", "no-cache");
        response.setHeader("Expires", "0");
        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(file.getName(), StandardCharsets.UTF_8));
        byte[] buff = new byte[81920];
        BufferedInputStream bis = null;
        OutputStream os;
        try {
            os = response.getOutputStream();
            bis = new BufferedInputStream(new FileInputStream(file));
            int i = bis.read(buff);
            while(i != -1) {
                os.write(buff, 0, i);
                os.flush();
                i = bis.read(buff);
            }
        } catch(IOException e) {
            throw new AppException(e.getMessage());
            //e.printStackTrace();
        } finally {
            if(bis != null) {
                try {
                    bis.close();
                } catch(IOException e) {
                    //e.printStackTrace();
                }
            }
        }
    }

    @ApiOperationSupport(order = 3)
    @ApiOperation(value = "删除文件")
    @ApiImplicitParam(name = "path", value = "文件路径", required = true)
    @ResponseBody
    @PostMapping(value = "/delete")
    public RestMessage delete(@RequestParam String path) {
        if(Helper.isBlank(path)) {
            return RestMessage.fail("请指定下载文件名称");
        }
        path = path.replace("\\","/");
        File file = Sys.buildFile(path);
        if(file.isDirectory()) {
            return RestMessage.fail("输入的路径不是一个有效的文件");
        }
        if(!file.exists()) {
            return RestMessage.fail("指定文件无效");
        }
        if(file.delete()) {
            return RestMessage.success();
        }
        return RestMessage.fail();
    }
}